From 8ce2d2224cac0d5540c36c017f3d28212457ed14 Mon Sep 17 00:00:00 2001 From: tsteven4 <13596209+tsteven4@users.noreply.github.com> Date: Wed, 29 May 2019 16:57:02 -0600 Subject: [PATCH] Track filter fix (#363) * Fix compatibility for track filter GUI<->CLI. Add a week unit for the track filter move option, in addition to the existing day, hour, minute and second units. Allow combination of units for track filter move option, e.g. 1w2d3h4m-5s = 1 week + 2 days + 3 hours + 4 minutes - 5 seconds. This matches historical use, and is expected by the GUI. Add the week unit to the GUI track filter ui. Change the limits on the track filter move specs: week: +/-10000 (unit didn't exit before) day,hour,minute,second: +/- 100000 (+/-2000 for day before, +/-100 on others). This resolves #357. This resolves #358. * add documentation for track filter move option. --- gui/filterdata.cc | 2 +- gui/filterdata.h | 5 +- gui/filterwidgets.cc | 10 ++-- gui/trackui.ui | 74 +++++++++++++++++++++++++-- trackfilter.cc | 52 +++++++++++-------- xmldoc/filters/options/track-move.xml | 24 +++++++++ 6 files changed, 133 insertions(+), 34 deletions(-) diff --git a/gui/filterdata.cc b/gui/filterdata.cc index 092cabde8..6fc304f14 100644 --- a/gui/filterdata.cc +++ b/gui/filterdata.cc @@ -136,7 +136,7 @@ QStringList TrackFilterData::makeOptionString() s += QString(",stop=%1").arg(optionDate(stopTime, TZ)); } if (move) { - s += QString(",move=%1d%2h%3m%4s").arg(days).arg(hours).arg(mins).arg(secs); + s += QString(",move=%1w%2d%3h%4m%5s").arg(weeks).arg(days).arg(hours).arg(mins).arg(secs); } if (title) { s += QString(",title=%1").arg(titleString); diff --git a/gui/filterdata.h b/gui/filterdata.h index 252084704..513249306 100644 --- a/gui/filterdata.h +++ b/gui/filterdata.h @@ -60,7 +60,7 @@ class TrackFilterData: public FilterData { public: TrackFilterData(): FilterData(), title(false), titleString(QString()), - move(false), days(0), hours(0), mins(0), secs(0), + move(false), weeks(0), days(0), hours(0), mins(0), secs(0), TZ(false), start(false), stop(false), @@ -98,6 +98,7 @@ public: sg.addVarSetting(new DateTimeSetting("trks.stopTime", stopTime)); sg.addVarSetting(new BoolSetting("trks.TZ", TZ)); sg.addVarSetting(new BoolSetting("trks.move", move)); + sg.addVarSetting(new IntSetting("trks.weeks", weeks)); sg.addVarSetting(new IntSetting("trks.days", days)); sg.addVarSetting(new IntSetting("trks.mins", mins)); sg.addVarSetting(new IntSetting("trks.hours", hours)); @@ -115,7 +116,7 @@ public: bool title; QString titleString; bool move; - int days, hours, mins, secs; + int weeks, days, hours, mins, secs; bool TZ; bool start; diff --git a/gui/filterwidgets.cc b/gui/filterwidgets.cc index ee241ae1e..10cf91496 100644 --- a/gui/filterwidgets.cc +++ b/gui/filterwidgets.cc @@ -32,6 +32,7 @@ TrackWidget::TrackWidget(QWidget* parent, TrackFilterData& tfd): FilterWidget(pa addCheckEnabler(ui.titleCheck, ui.titleText); addCheckEnabler(ui.moveCheck, (QList () + << ui.weeksLabel << ui.weeksSpin << ui.daysLabel << ui.daysSpin << ui.hoursLabel<< ui.hoursSpin << ui.minsLabel << ui.minsSpin @@ -76,10 +77,11 @@ TrackWidget::TrackWidget(QWidget* parent, TrackFilterData& tfd): FilterWidget(pa fopts << new BoolFilterOption(tfd.course, ui.courseCheck); fopts << new BoolFilterOption(tfd.speed, ui.speedCheck); - fopts << new IntSpinFilterOption(tfd.days, ui.daysSpin, -2000, 2000); - fopts << new IntSpinFilterOption(tfd.hours, ui.hoursSpin); - fopts << new IntSpinFilterOption(tfd.mins, ui.minsSpin); - fopts << new IntSpinFilterOption(tfd.secs, ui.secsSpin); + fopts << new IntSpinFilterOption(tfd.weeks, ui.weeksSpin, ui.weeksSpin->minimum(), ui.weeksSpin->maximum()); + fopts << new IntSpinFilterOption(tfd.days, ui.daysSpin, ui.daysSpin->minimum(), ui.daysSpin->maximum()); + fopts << new IntSpinFilterOption(tfd.hours, ui.hoursSpin, ui.hoursSpin->minimum(), ui.hoursSpin->maximum()); + fopts << new IntSpinFilterOption(tfd.mins, ui.minsSpin, ui.minsSpin->minimum(), ui.minsSpin->maximum()); + fopts << new IntSpinFilterOption(tfd.secs, ui.secsSpin, ui.secsSpin->minimum(), ui.secsSpin->maximum()); fopts << new IntSpinFilterOption(tfd.splitTime, ui.splitTimeSpin, 0, 1000); fopts << new IntSpinFilterOption(tfd.splitDist, ui.splitDistSpin, 0, 5280); diff --git a/gui/trackui.ui b/gui/trackui.ui index 9e42c93bf..172b7b04d 100644 --- a/gui/trackui.ui +++ b/gui/trackui.ui @@ -7,7 +7,7 @@ 0 0 663 - 248 + 270 @@ -73,9 +73,43 @@ This option changes the time of all trackpoints. This might be useful if your tr + + + + + true + + + -10000 + + + 10000 + + + + + + + weeks + + + + + + - + + + true + + + -100000 + + + 100000 + + @@ -89,7 +123,17 @@ This option changes the time of all trackpoints. This might be useful if your tr - + + + true + + + -100000 + + + 100000 + + @@ -103,7 +147,17 @@ This option changes the time of all trackpoints. This might be useful if your tr - + + + true + + + -100000 + + + 100000 + + @@ -117,7 +171,17 @@ This option changes the time of all trackpoints. This might be useful if your tr - + + + true + + + -100000 + + + 100000 + + diff --git a/trackfilter.cc b/trackfilter.cc index 1778a989e..c1a592e60 100644 --- a/trackfilter.cc +++ b/trackfilter.cc @@ -78,34 +78,42 @@ int TrackFilter::trackfilter_opt_count() qint64 TrackFilter::trackfilter_parse_time_opt(const char* arg) { - qint64 result; + qint64 result = 0; - QRegularExpression re("^([+-]?\\d+)([dhms])$", QRegularExpression::CaseInsensitiveOption); + QRegularExpression re("^([+-]?\\d+)([wdhms])(?:([+-]?\\d+)([wdhms]))?(?:([+-]?\\d+)([wdhms]))?(?:([+-]?\\d+)([wdhms]))?(?:([+-]?\\d+)([wdhms]))?$", QRegularExpression::CaseInsensitiveOption); assert(re.isValid()); QRegularExpressionMatch match = re.match(arg); if (match.hasMatch()) { - bool ok; - result = match.captured(1).toLong(&ok); - if (!ok) { - fatal(MYNAME "-time: invalid quantity in move option \"%s\"!\n", qPrintable(match.captured(1))); - } + int lastindex = match.lastCapturedIndex(); + for (int idx = 1; idx < lastindex; idx += 2) { + bool ok; + qint64 partial = match.captured(idx).toLong(&ok); + if (!ok) { + fatal(MYNAME "-time: invalid quantity in move option \"%s\"!\n", qPrintable(match.captured(idx))); + } - switch (match.captured(2).at(0).toLower().toLatin1()) { - case 'd': - result *= SECONDS_PER_DAY; - break; - case 'h': - result *= SECONDS_PER_HOUR; - break; - case 'm': - result *= 60; - break; - case 's': - break; - default: - fatal(MYNAME "-time: invalid unit in move option \"%s\"!\n", qPrintable(match.captured(2))); - } + switch (match.captured(idx+1).at(0).toLower().toLatin1()) { + case 'w': + partial *= SECONDS_PER_DAY * 7; + break; + case 'd': + partial *= SECONDS_PER_DAY; + break; + case 'h': + partial *= SECONDS_PER_HOUR; + break; + case 'm': + partial *= 60; + break; + case 's': + break; + default: + fatal(MYNAME "-time: invalid unit in move option \"%s\"!\n", qPrintable(match.captured(idx+1))); + } + result += partial; + + } #ifdef TRACKF_DBG qDebug() << MYNAME "-time option: shift =" << result << "seconds"; #endif diff --git a/xmldoc/filters/options/track-move.xml b/xmldoc/filters/options/track-move.xml index 22452828a..e3dd19ff7 100644 --- a/xmldoc/filters/options/track-move.xml +++ b/xmldoc/filters/options/track-move.xml @@ -2,6 +2,13 @@ This option changes the time of all trackpoints. This might be useful if your track must be moved by one or more hours because of an incorrect time zone. +It can also be useful to correct tracks for week number roll over problems. + + +The value of this option is a series of integer and unit pairs. Each integer may include a +leading '+' or '-' sign. Positive integers shift the tracks later, while negative integers shift +the tracks earlier. If no sign is provided the integer is assumed to be nonnegative. +Possible units are w for weeks, d for days, h for hours, m for minutes and s for seconds. Time-shifting a track with the track filter @@ -10,4 +17,21 @@ The following command line will shift all tracks to be one hour later. gpsbabel -t -i gpx -f in.gpx -x track,move=+1h -o gpx -F out.gpx + +Time-shifting a track with the track filter to correct WNRO + +The following command line will shift all tracks to be 1024 weeks later. Because the GPS Week Number +is transmitted modulo 1024 there is the possibility that the recovered timestamp will be off by +a multiple of 1024 weeks. + +gpsbabel -t -i gpx -f in.gpx -x track,move=+1024w -o gpx -F out.gpx + + +Time-shifting a track with the track filter with combined units + +The following command lines will each shift all tracks to be 1 hour and 1 minute earlier, i.e. 61 minutes earlier. + +gpsbabel -t -i gpx -f in.gpx -x track,move=-1h-1m -o gpx -F out.gpx +gpsbabel -t -i gpx -f in.gpx -x track,move=-61m -o gpx -F out.gpx + -- 2.30.2